﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;
namespace RecruitStudents.Utility.Json
{
    /// <summary>
    /// Json序列化和反序列化辅助类 
    /// </summary>
    public class JsonHelper
    {

        public static string GetJsonString(string state, string retcode, string message, string data)
        {
            JsonRetData strJson = new JsonRetData()
            {
                State = state,
                Message = message,
                RetCode = retcode,
                RetData = data
            };
            return strJson.AssemblyJson();

        }

        public static string GetJsonStringPad(string state, string retcode, string message, string data)
        {
            JsonRetData strJson = new JsonRetData()
            {
                State = state,
                Message = message,
                RetCode = retcode,
                RetData = data
            };
            return strJson.AssemblyJson();

        }


        /// <summary> 
        /// Json序列化 
        /// </summary> 
        public static string JsonSerializer<T>(T obj)
        {
            string jsonString = string.Empty;
            try
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                using (MemoryStream ms = new MemoryStream())
                {
                    serializer.WriteObject(ms, obj);
                    jsonString = Encoding.UTF8.GetString(ms.ToArray());
                }
            }
            catch
            {
                jsonString = string.Empty;
            }
            return jsonString;
        }
        /// <summary> 
        /// Json反序列化
        /// </summary> 
        public static T JsonDeserialize<T>(string jsonString)
        {
            T obj = Activator.CreateInstance<T>();
            try
            {
                using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
                {
                    DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());//typeof(T)
                    T jsonObject = (T)ser.ReadObject(ms);
                    ms.Close();
                    return jsonObject;
                }
            }
            catch
            {
                return default(T);
            }
        }
        /// <summary>
        /// 将 DataTable 序列化成 json 字符串
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string DataTableToJson(DataTable dt)
        {
            if (dt == null || dt.Rows.Count == 0)
            {
                return "";
            }
            JavaScriptSerializer myJson = new JavaScriptSerializer();
            myJson.MaxJsonLength = Int32.MaxValue; //取得最大数值
            List<Dictionary<string, string>> list = new List<Dictionary<string, string>>();
            Dictionary<string, string> result;
            foreach (DataRow dr in dt.Rows)
            {
                result = new Dictionary<string, string>();
                foreach (DataColumn dc in dt.Columns)
                {
                    result.Add(dc.ColumnName, dr[dc].ToString());
                }
                list.Add(result);
            }
            return myJson.Serialize(list);
        }
        /// <summary>
        /// 不需要分页
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string Serialize(DataTable dt)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            serializer.MaxJsonLength = Int32.MaxValue; //取得最大数值
            List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
            Dictionary<string, object> result;
            foreach (DataRow dr in dt.Rows)
            {
                result = new Dictionary<string, object>();
                foreach (DataColumn dc in dt.Columns)
                {
                    result.Add(dc.ColumnName, dr[dc].ToString());
                }
                list.Add(result);
            }
            return serializer.Serialize(list);
        }
        /// <summary>
        /// 将对象序列化成 json 字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectToJson(object obj)
        {
            if (obj == null)
            {
                return string.Empty;
            }
            JavaScriptSerializer myJson = new JavaScriptSerializer();
            myJson.MaxJsonLength = Int32.MaxValue; //取得最大数值
            return myJson.Serialize(obj);
        }
        /// <summary>
        /// 将 json 字符串反序列化成对象
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static object JsonToObject(string json)
        {
            if (string.IsNullOrEmpty(json))
            {
                return null;
            }
            JavaScriptSerializer myJson = new JavaScriptSerializer();
            myJson.MaxJsonLength = Int32.MaxValue; //取得最大数值
            return myJson.DeserializeObject(json);
        }
        /// <summary>
        /// 将 json 字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T JsonToObject<T>(string json)
        {
            if (string.IsNullOrEmpty(json))
            {
                return default(T);
            }
            JavaScriptSerializer myJson = new JavaScriptSerializer();
            myJson.MaxJsonLength = Int32.MaxValue; //取得最大数值
            return myJson.Deserialize<T>(json);
        }
        /// <summary>
        /// JSON序列化
        /// </summary>
        public static string JsonSerializerDate<T>(T t)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                ser.WriteObject(ms, t);
                string jsonString = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                //替换Json的Date字符串
                string p = @"\\/Date\((\d+)\+\d+\)\\/";
                MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertJsonDateToDateString);
                Regex reg = new Regex(p);
                jsonString = reg.Replace(jsonString, matchEvaluator);
                jsonString = jsonString.Replace("_", "");
                return jsonString;
            }
        }
        /// <summary>
        /// JSON反序列化
        /// </summary>
        public static T JsonDeserializeDate<T>(string jsonString)
        {
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
            {
                //将"yyyy-MM-dd HH:mm:ss"格式的字符串转为"\/Date(1294499956278+0800)\/"格式
                string p = @"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}";
                MatchEvaluator matchEvaluator = new MatchEvaluator(ConvertDateStringToJsonDate);
                Regex reg = new Regex(p);
                jsonString = reg.Replace(jsonString, matchEvaluator);
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                T obj = (T)ser.ReadObject(ms);
                return obj;
            }
        }
        /// <summary>
        /// 将Json序列化的时间由/Date(1294499956278+0800)转为字符串
        /// </summary>
        private static string ConvertJsonDateToDateString(Match m)
        {
            string result = string.Empty;
            DateTime dt = new DateTime(1970, 1, 1);
            dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));
            dt = dt.ToLocalTime();
            result = dt.ToString("yyyy-MM-dd HH:mm:ss");
            return result;
        }
        /// <summary>
        /// 将时间字符串转为Json时间
        /// </summary>
        private static string ConvertDateStringToJsonDate(Match m)
        {
            string result = string.Empty;
            DateTime dt = DateTime.Parse(m.Groups[0].Value);
            dt = dt.ToUniversalTime();
            TimeSpan ts = dt - DateTime.Parse("1970-01-01");
            result = string.Format("\\/Date({0}+0800)\\/", ts.TotalMilliseconds);
            return result;
        }


        #region Json 字符串 转换为 DataTable数据集合
        /// <summary>
        /// Json 字符串 转换为 DataTable数据集合
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(string json)
        {
            if (string.IsNullOrEmpty(json))
                return null;
            DataTable dataTable = new DataTable();  //实例化
            DataTable result;
            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();            
            javaScriptSerializer.MaxJsonLength = Int32.MaxValue; //取得最大数值
            List<Dictionary<string, object>> arrayList = javaScriptSerializer.Deserialize<List<Dictionary<string, object>>>(json);
            if (arrayList.Count > 0)
            {
                foreach (Dictionary<string, object> dictionary in arrayList)
                {
                    if (dataTable.Columns.Count == 0)
                    {
                        foreach (string current in dictionary.Keys)
                        {
                            dataTable.Columns.Add(current, dictionary[current].GetType());
                        }
                    }
                    if (dictionary.Keys.Count<string>() == 0)
                    {
                        result = dataTable;
                        return result;
                    }
                    DataRow dataRow = dataTable.NewRow();
                    foreach (string current in dictionary.Keys)
                    {
                        dataRow[current] = dictionary[current];
                    }
                    dataTable.Rows.Add(dataRow); //循环添加行到DataTable中
                }
            }
            result = dataTable;
            return result;
        }
        #endregion
    }
}
